package meta

import (
	"encoding/json"
	"fmt"
	"strings"
)

const (
	KindConfig   = "config"
	KindInstance = "instance"
	kindAgent    = "agent"
)

type Agent struct {
	Guid     string `json:"guid" yaml:"guid" xorm:"guid"`
	IP       string `json:"ip_address" yaml:"ip_address" xorm:"ip"`
	MAC      string `json:"mac_address" yaml:"mac_address" xorm:"mac"`
	CPUs     string `json:"cpu_cores" yaml:"cpu_cores" xorm:"cpu_cores"`
	MEM      string `json:"memory_bytes" yaml:"memory_bytes" xorm:"mem_size"`
	OS       string `json:"os" yaml:"os" xorm:"os"`
	Arch     string `json:"arch" yaml:"arch" xorm:"arch"`
	Hostname string `json:"host_name" yaml:"host_name" xorm:"hostname"`
	Area     string `json:"area" yaml:"area" xorm:"area"`
	Status   string `json:"status" yaml:"status" xorm:"status"`
	Services string `json:"services" yaml:"services" xorm:"services"`
	Tags     string `json:"tags" yaml:"tags" xorm:"tags"`
}

type AgentInfo struct {
	Guid     string `json:"guid" yaml:"guid" xorm:"guid"`
	IP       string `json:"ip_address" yaml:"ip_address" xorm:"ip"`
	MAC      string `json:"mac_address" yaml:"mac_address" xorm:"mac"`
	CPUs     string `json:"cpu_cores" yaml:"cpu_cores" xorm:"cpu_cores"`
	MEM      string `json:"memory_bytes" yaml:"memory_bytes" xorm:"mem_size"`
	OS       string `json:"os" yaml:"os" xorm:"os"`
	Arch     string `json:"arch" yaml:"arch" xorm:"arch"`
	Hostname string `json:"host_name" yaml:"host_name" xorm:"hostname"`
	Area     string `json:"area" yaml:"area" xorm:"area"`
}

type AgentStatus struct {
	Guid     string `json:"guid" yaml:"guid" xorm:"guid"`
	Status   string `json:"status" yaml:"status" xorm:"status"`
	Services string `json:"services" yaml:"services" xorm:"services"`
	Tags     string `json:"tags" yaml:"tags" xorm:"tags"`
	//Instances string `json:"instances" yaml:"instances" xorm:"instances"`
}

type Config struct {
	Label       string `json:"label" yaml:"label" xorm:"label"`
	Name        string `json:"name" yaml:"name" xorm:"name"`
	Platform    string `json:"platform" yaml:"platform" xorm:"platform"`
	ConfigValue string `json:"config" yaml:"config" xorm:"config_json"`
}

type Instance struct {
	Label         string `json:"label" yaml:"label" xorm:"label"`
	Guid          string `json:"guid" yaml:"guid" xorm:"guid"`
	Name          string `json:"name" yaml:"name" xorm:"name"`
	Platform      string `json:"platform" yaml:"platform" xorm:"platform"`
	InstanceValue string `json:"instance" yaml:"instance" xorm:"instance_json"`
}

type ScheduleMiddleResults struct {
	Instances      *Instance              `json:"instances_guid" yaml:"instances_guid" xorm:"instances_guid"`
	InstancesCells map[string]interface{} `json:"instances_cells" yaml:"instances_cells" xorm:"instances_cells"`
	ScheduleMap    map[string][]Agent     `json:"schedule_map" yaml:"schedule_map" xorm:"schedule_map"`
}

type ScheduleResults struct {
	InstancesGuid  string `json:"instances_guid" yaml:"instances_guid" xorm:"instances_guid"`
	InstancesCells string `json:"instances_cells" yaml:"instances_cells" xorm:"instances_cells"`
	ScheduleMap    string `json:"schedule_map" yaml:"schedule_map" xorm:"schedule_map"`
}

func DeCodeScheduleMaps(maps string) (map[string]string, error) {
	m := make(map[string]string)
	err := json.Unmarshal([]byte(maps), &m)
	if err != nil {
		return nil, fmt.Errorf("unmarshall %v", err)
	}
	return m, nil
}

func EnCodeScheduleMaps(maps map[string]string) string {
	bts, _ := json.Marshal(maps)
	return string(bts)
}

func DeCodeScheduleCells(cells string) []string {
	return strings.Split(cells, ",")
}

func EnCodeScheduleCells(cells []string) string {
	return strings.Join(cells, ",")
}

type StrategyLinks struct {
	StrategyGuid     string `json:"strategy_guid" yaml:"strategy_guid" xorm:"strategy_guid"`
	ApplicationGuids string `json:"application_guids" yaml:"application_guids" xorm:"application_guids"`
}

func DeCodeMapInstances(ins string) []string {
	return strings.Split(ins, ",")
}

func EnCodeMapInstances(ins []string) string {
	return strings.Join(ins, ",")
}

func DeCodeTags(tag string) (map[string]string, error) {
	var tags map[string]string
	if err := json.Unmarshal([]byte(tag), &tags); err != nil {
		return nil, err
	}
	return tags, nil
}

func EnCodeLinks(guids []string) string {
	return strings.Join(guids, ",")
}

func DeCodeLinks(guids string) []string {
	if guids == "" {
		return nil
	}
	return strings.Split(guids, ",")
}

type Tree struct {
	UpdateTime   string `json:"update_time" yaml:"update_time" xorm:"update_time"`
	ResourceTree string `json:"resource_tree" yaml:"resource_tree" xorm:"resource_tree"`
}

type Dag struct {
	UpdateTime  string `json:"update_time" yaml:"update_time" xorm:"update_time"`
	InstanceDag string `json:"instances_dag" yaml:"instances_dag" xorm:"instances_dag"`
}

type InstanceStatus struct {
	Contaienrs map[string]map[string]interface{} `json:"contaienrs" yaml:"contaienrs" xorm:"contaienrs"`
	State      string                            `json:"state" yaml:"state" xorm:"state"`
}

type MetricsInstancesList struct {
	GuidList interface{} `json:"guids" yaml:"guids" xorm:"guids"`
}

type Metrics struct {
	Metrics interface{} `json:"metrics" yaml:"metrics" xorm:"metrics"`
}

type Logs struct {
	Logs       interface{} `json:"logs" yaml:"logs" xorm:"logs"`
	LogBuckets interface{} `json:"log_buckets" yaml:"log_buckets" xorm:"log_buckets"`
}
